from numpy import *

def loadDataSet():
    postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
                 ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
                 ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
                 ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
                 ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
                 ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    classVec = [0,1,0,1,0,1]    #1 is abusive, 0 not
    return postingList,classVec


def createVocabList(dataSet):
	vocSet = set([])
	for doc in dataSet:
		vocSet = vocSet | set(doc)
	return list(vocSet)


def setOfWords2Vec(vocabList, inputSet):
	returnVec = [0] * len(vocabList)
	for word in inputSet:
		if word in vocabList:
			returnVec[vocabList.index(word)] = 1
		else:
			print("The word: %s is not in my vocabulary!" % word)
	return returnVec



def trainNB0(trainMatrix, trainCategory):
	numTrainDocs = len(trainMatrix)
	numWords = len(trainMatrix[0])
	pAbusive = sum(trainCategory) / float(numTrainDocs)
	p0Num = ones(numWords); p1Num = ones(numWords)
	p0Denom = 2.0; p1Denom = 2.0
	for i in range(numTrainDocs):
		if trainCategory[i] == 1:
			p1Num += trainMatrix[i]
			p1Denom += sum(trainMatrix[i])
		else:
			p0Num += trainMatrix[i]
			p0Denom += sum(trainMatrix[i])
	p1Vect = log(p1Num / p1Denom + 1)
	p0Vect = log(p0Num / p0Denom + 1)
	return p0Vect, p1Vect, pAbusive 



dataSet, classVec = loadDataSet()
# print(dataSet)
vocablist = createVocabList(dataSet)
# print(vocablist)
vocablist0 = setOfWords2Vec(vocablist, dataSet[0])
# print(vocablist0)
trainMat = []
for post in dataSet:
	# print(post)
	trainMat.append(setOfWords2Vec(vocablist, post))
# print(trainMat)

p0V, p1V, pAb = trainNB0(trainMat, classVec)
# print(p0V)
# print(p1V)
# print(pAb)



def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
	print(vec2Classify)
	print(p1V)
	print(vec2Classify * p1V)
	p1 = sum(vec2Classify * p1Vec) + log(pClass1)
	p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
	print(p1, p0)
	if p1 > p0:
		return 1 
	else:
		return 0 


def testingNB():
	listOPosts, listClasses = loadDataSet()
	myVocabList = createVocabList(listOPosts)
	trainMat = []
	for postinDoc in listOPosts:
		trainMat.append(setOfWords2Vec(myVocabList, sspostinDoc))
	p0V, p1V, pAb = trainNB0(array(trainMat), array(listClasses))
	
	testEntry = ['love', 'my', 'dalmation']
	thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
	print(testEntry, 'classified as:', classifyNB(thisDoc, p0V, p1V, pAb))

	testEntry = ['stupid', 'garbage']
	thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
	print(testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb))


testingNB()



def bagOfWords2VecMN(vocabList, inputSet):
	returnVec = [0] * len(vocabList)
	for word in inputSet:
		if word in inputSet:
			returnVec[vocabList.index(word)] += 1
	return returnVec 



def textParse(bigString):
	import re 
	listOfTokens = re.split(r'\w*', bigString)
	return [tok.lower().strip() for tok in listOfTokens if len(tok) > 2]


def spamTest():
	docList = []; classList = []; fullText=[]
	for i in range(1, 26):
		wordList = textParse(open('email/spam/%d.txt' % i).read())
		docList.append(wordList)
		fullText.extend(wordList)
		classList.append(1)
		wordList = textParse(open('email/ham/%d.txt' % i, encoding='cp1252').read())
		docList.append(wordList)
		fullText.extend(wordList)
		classList.append(0)
	vocabList = createVocabList(docList)
	trainingSet = list(range(50)); testSet=[]
	for i in range(10):
		randIndex = int(random.uniform(0, len(trainingSet)))
		testSet.append(trainingSet[randIndex])
		del (trainingSet[randIndex])
	trainMat = []; trainClasses = []
	for docIndex in trainingSet:
		trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))
		trainClasses.append(classList[docIndex])
	p0V, p1V, pSpam = trainNB0(array(trainMat), array(trainClasses))
	errorCount = 0 
	for docIndex in testSet:
		wordVector = bagOfWords2VecMN(vocabList, docList[docIndex])
		if classifyNB(array(wordVector), p0V, p1V, pSpam) != classList[docIndex]:
			errorCount += 1
			print("classification error:", docList[docIndex])
	print("The error rate is:", float(errorCount) / len(testSet))



# spamTest()

